package com.david.reader.utils

import android.content.Context
import android.net.Uri
import android.os.Environment
import android.text.TextUtils
import android.widget.Toast
import androidx.documentfile.provider.DocumentFile
import com.david.core.event.MyEventBus
import com.david.core.utils.MMKVUtil
import com.david.reader.bean.BookBean
import com.david.reader.ReaderApplication
import com.david.reader.event.BookAddShellEvent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.*
import java.util.*
import kotlin.collections.ArrayList

object FileUtil {
    fun writeFileInfo(bookBeans: ArrayList<BookBean>){
        ReaderApplication.instance.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)?.let {
            val bookFile = File(it.absolutePath + "/bookList")
            if (!bookFile.exists()) {
                bookFile.createNewFile()
            }

            val fos = ObjectOutputStream(FileOutputStream(bookFile))
            fos.writeObject(bookBeans)
            fos.flush()
            fos.close()
        }
    }

    fun getFileListInfo(): ArrayList<BookBean> {
        var result = ArrayList<BookBean>()
        ReaderApplication.instance.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)?.let {
            val bookFile = File(it.absolutePath + "/bookList")
            if (bookFile.exists()) {
                val fis = ObjectInputStream(FileInputStream(bookFile))
                result = fis.readObject() as ArrayList<BookBean>

                fis.close()
            }
        }
        return result
    }

    fun copyFileToCache(context: Context, uri: Uri){
        copyFileToCache(context, uri, null)
    }

    fun copyFileToCache(context: Context, uri: Uri, onFileCopiedListener:OnFileCopiedListener?){
        val name = getUriName(uri)
        val absolutePath = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)?.absolutePath + "/" + name
        if (File(absolutePath).exists()) {
            Toast.makeText(context, "文件已添加过", Toast.LENGTH_LONG).show()
            onFileCopiedListener?.onCopyFailed("文件已添加过")
            return
        }
        CoroutineScope(Dispatchers.IO).launch {
            writeCacheFile(context, uri)
            onFileCopiedListener?.onFileCopy(name, absolutePath)
        }
    }

    fun writeCacheFile(context: Context, uri: Uri){
        val inputStream: InputStream? = context.contentResolver.openInputStream(uri)
        inputStream?.apply {
            val name = getUriName(uri)
            val file = File(
                context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)?.absolutePath + "/" + name
            )
            if (!file.exists()) {
                val fos = FileOutputStream(file)
                val bytes = ByteArray(512)
                var length = inputStream.read(bytes)
                while (length > 0) {
                    fos.write(bytes, 0, length)
                    fos.flush()
                    length = inputStream.read(bytes, 0, length)
                }
                inputStream.close()
                fos.close()
            }

            MyEventBus.getDefault().post(BookAddShellEvent(
                name, file.absolutePath, if (uri.toString().lowercase(
                    Locale.getDefault()).endsWith(".txt")) 0 else 1))
        }
    }

    fun getUriName(uri: Uri): String {
        return if (!TextUtils.isEmpty(uri.path) && uri.path!!.contains(".")) {
            val name = uri.path?.substring(
                uri.path!!.lastIndexOf("/") + 1)

            name!!
        } else {
            getFileRealNameFromUri(ReaderApplication.instance, uri)!!
        }

    }

    /**
     * 获取app中缓存的文件路径
     */
    fun getDocCachePath(context: Context, name: String):String{
        return context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)?.absolutePath + "/" + name
    }


    fun getFileRealNameFromUri(context: Context?, fileUri: Uri?): String? {
        if (context == null || fileUri == null) return null
        val documentFile = DocumentFile.fromSingleUri(context, fileUri) ?: return null
        return documentFile.name
    }

    fun getDocumentsPath(): String{
        val documentPath = MMKVUtil.getString("documentPath", "")
        if (!TextUtils.isEmpty(documentPath)) {
          return documentPath
        } else {
            val files = Environment.getExternalStorageDirectory().listFiles()
            for (file in files) {
                if (file.name.lowercase() == "documents") {
                    return file.absolutePath
                }
            }
            return ""
        }
    }
}

interface OnFileCopiedListener{
    fun onFileCopy(name:String, path:String)
    fun onCopyFailed(path:String)
}